<template>
  <div class="form-field" :class="fieldClasses">
    <el-form-item
      :label="config.title"
      :prop="config.key"
      :required="isRequired"
      :error="errorMessage"
      :label-width="labelWidth"
    >
      <!-- 字段描述 -->
      <template #label v-if="config.description">
        <span>{{ config.title }}</span>
        <el-tooltip :content="config.description" placement="top">
          <el-icon class="field-description-icon"><QuestionFilled /></el-icon>
        </el-tooltip>
      </template>

      <!-- 动态渲染不同类型的表单组件 -->
      <component
        :is="fieldComponent"
        v-model="fieldValue"
        v-bind="componentProps"
        :disabled="isDisabled"
        :placeholder="config.placeholder"
        @change="handleChange"
        @focus="handleFocus"
        @blur="handleBlur"
        @input="handleInput"
      />
      
      <!-- 自定义插槽 -->
      <slot name="suffix" :config="config" :value="fieldValue"></slot>
    </el-form-item>
  </div>
</template>

<script setup>
import { computed, ref, watch, onMounted, onUnmounted } from 'vue'
import { ElFormItem, ElIcon, ElTooltip } from 'element-plus'
import { QuestionFilled } from '@element-plus/icons-vue'
import { UI_TYPES, EVENT_TYPES } from '@/types/schema.js'

// 导入各种字段组件
import FormInput from './fields/FormInput.vue'
import FormTextarea from './fields/FormTextarea.vue'
import FormSelect from './fields/FormSelect.vue'
import FormRadio from './fields/FormRadio.vue'
import FormCheckbox from './fields/FormCheckbox.vue'
import FormSwitch from './fields/FormSwitch.vue'
import FormDatePicker from './fields/FormDatePicker.vue'
import FormTimePicker from './fields/FormTimePicker.vue'
import FormNumberInput from './fields/FormNumberInput.vue'
import FormSlider from './fields/FormSlider.vue'
import FormRate from './fields/FormRate.vue'
import FormUpload from './fields/FormUpload.vue'

const props = defineProps({
  config: {
    type: Object,
    required: true
  },
  modelValue: {
    type: [String, Number, Boolean, Array, Object],
    default: undefined
  },
  eventBus: {
    type: Object,
    required: true
  },
  labelWidth: {
    type: String,
    default: '120px'
  }
})

const emit = defineEmits(['update:modelValue', 'change', 'focus', 'blur', 'input'])

// 字段值
const fieldValue = computed({
  get() {
    return props.modelValue
  },
  set(value) {
    emit('update:modelValue', value)
  }
})

// 字段状态
const fieldState = computed(() => {
  return props.eventBus.getFieldState(props.config.key) || {}
})

// 是否必填
const isRequired = computed(() => {
  return fieldState.value.required !== undefined 
    ? fieldState.value.required 
    : props.config.required
})

// 是否禁用
const isDisabled = computed(() => {
  return fieldState.value.disabled !== undefined 
    ? fieldState.value.disabled 
    : props.config.ui?.disabled || false
})

// 是否可见
const isVisible = computed(() => {
  return fieldState.value.visible !== undefined 
    ? fieldState.value.visible 
    : props.config.visible !== false
})

// 错误消息
const errorMessage = computed(() => {
  return fieldState.value.errorMessage || ''
})

// 字段样式类
const fieldClasses = computed(() => {
  return [
    `field-${props.config.ui?.type || 'input'}`,
    {
      'field-required': isRequired.value,
      'field-disabled': isDisabled.value,
      'field-hidden': !isVisible.value,
      'field-error': !!errorMessage.value
    },
    props.config.ui?.class || ''
  ]
})

// 组件映射
const componentMap = {
  [UI_TYPES.INPUT]: FormInput,
  [UI_TYPES.TEXTAREA]: FormTextarea,
  [UI_TYPES.SELECT]: FormSelect,
  [UI_TYPES.RADIO]: FormRadio,
  [UI_TYPES.CHECKBOX]: FormCheckbox,
  [UI_TYPES.SWITCH]: FormSwitch,
  [UI_TYPES.DATE_PICKER]: FormDatePicker,
  [UI_TYPES.TIME_PICKER]: FormTimePicker,
  [UI_TYPES.NUMBER_INPUT]: FormNumberInput,
  [UI_TYPES.SLIDER]: FormSlider,
  [UI_TYPES.RATE]: FormRate,
  [UI_TYPES.UPLOAD]: FormUpload
}

// 当前字段组件
const fieldComponent = computed(() => {
  const uiType = props.config.ui?.type || UI_TYPES.INPUT
  return componentMap[uiType] || FormInput
})

// 组件属性
const componentProps = computed(() => {
  const ui = props.config.ui || {}
  const state = fieldState.value
  
  return {
    ...ui.attrs,
    ...state.attrs,
    size: ui.size || 'default',
    clearable: ui.clearable !== false,
    options: state.options || ui.options || [],
    style: {
      ...ui.style,
      ...state.style
    }
  }
})

// 事件处理
const handleChange = (value) => {
  emit('change', value)
  props.eventBus.setFieldValue(props.config.key, value)
  triggerEvent(EVENT_TYPES.CHANGE, value)
}

const handleFocus = (event) => {
  emit('focus', event)
  triggerEvent(EVENT_TYPES.FOCUS, fieldValue.value, event)
}

const handleBlur = (event) => {
  emit('blur', event)
  triggerEvent(EVENT_TYPES.BLUR, fieldValue.value, event)
}

const handleInput = (value) => {
  emit('input', value)
  triggerEvent(EVENT_TYPES.INPUT, value)
}

// 触发自定义事件
const triggerEvent = (eventType, value, nativeEvent = null) => {
  const eventConfig = props.config.events?.[eventType]
  if (!eventConfig) return

  // 触发事件总线事件
  props.eventBus.emit(`field:${eventType}`, {
    fieldKey: props.config.key,
    value,
    config: props.config,
    nativeEvent
  }, props.config.key)

  // 执行自定义事件处理器
  if (typeof eventConfig === 'function') {
    eventConfig(value, props.config, nativeEvent)
  } else if (typeof eventConfig === 'object' && eventConfig.handler) {
    eventConfig.handler(value, props.config, nativeEvent)
  }
}

// 监听字段状态变化
watch(() => fieldState.value, (newState, oldState) => {
  // 可见性变化时触发事件
  if (newState.visible !== oldState?.visible) {
    props.eventBus.emit('field:visibility:change', {
      fieldKey: props.config.key,
      visible: newState.visible,
      config: props.config
    }, props.config.key)
  }

  // 禁用状态变化时触发事件
  if (newState.disabled !== oldState?.disabled) {
    props.eventBus.emit('field:disabled:change', {
      fieldKey: props.config.key,
      disabled: newState.disabled,
      config: props.config
    }, props.config.key)
  }
}, { deep: true })

// 初始化字段值到事件总线
onMounted(() => {
  if (props.modelValue !== undefined) {
    props.eventBus.setFieldValue(props.config.key, props.modelValue, false)
  } else if (props.config.defaultValue !== undefined) {
    props.eventBus.setFieldValue(props.config.key, props.config.defaultValue, false)
    emit('update:modelValue', props.config.defaultValue)
  }
})

// 清理事件监听器
onUnmounted(() => {
  props.eventBus.removeFieldListeners(props.config.key)
})
</script>

<style scoped>
.form-field {
  width: 100%;
}

.field-hidden {
  display: none;
}

.field-description-icon {
  margin-left: 4px;
  color: #999;
  cursor: help;
}

.field-error :deep(.el-input__inner),
.field-error :deep(.el-textarea__inner),
.field-error :deep(.el-select__input) {
  border-color: var(--el-color-danger);
}

.field-disabled {
  opacity: 0.6;
}
</style>